#ifndef __PVMSOFTMIXERFASTINT_H__
#define __PVMSOFTMIXERFASTINT_H__

#include "lib/softwaremixer/pvmsoftmixer.h"

#include "lib/memory/pvmmemory.h"

//realize software mixer
class PVMSoftMixerFastInt : public IPVMSoftMixer, public PVMAllocableObject
{
public:
	PVMSoftMixerFastInt();
	virtual ~PVMSoftMixerFastInt();

	virtual void ResizeRenderBuffer(pvm_uint32 bufferSizeInBytes);
	virtual pvm_uint32 GetRenderBufferSizeInBytes();
	virtual pvm_bool HasMoreData();
	virtual pvm_uint32 FillBuffer(void * buffer, pvm_uint32 bufferSizeInSamples);

	virtual void StopAll();

	virtual pvm_bool Init(pvm_uint32 maxVoices, pvm_uint32 sampleRate, pvm_uint32 bitsPerSample, pvm_uint32 chanelsNum);
	virtual void DeInit();
	virtual pvm_bool IsInitialized();
	virtual pvm_uint32 GetMaxVoices();

	virtual void SetGlobalVolume(pvm_uint32 volume);
	virtual pvm_uint32 GetGlobalVolume();

	virtual pvm_int32 Play(IPVMVoice *chanel, pvm_uint32 voiceNumAndFlags, TVoiceCallbackProc callbackProc, pvm_uint32 callbackPeriod, void* calbackParam);
	virtual pvm_bool Stop(pvm_uint32 chanelNum);
	virtual pvm_bool IsVoiceFree(pvm_uint32 chanelNum);

	virtual pvm_bool SetPanning(pvm_uint32 chanelNum, pvm_int32 value);
	virtual pvm_bool SetVolume(pvm_uint32 chanelNum, pvm_int32 value);
	virtual pvm_bool SetLoopCount(pvm_uint32 chanelNum, pvm_int32 value);
	virtual pvm_bool SetLoopInSamples(pvm_uint32 chanelNum, pvm_int64 loopFrom, pvm_int64 loopTo);
	virtual pvm_bool SetPause(pvm_uint32 chanelNum, pvm_bool value);
	virtual pvm_bool SetRenderSilentVoice(pvm_uint32 chanelNum, pvm_bool value);
	virtual pvm_bool SetRate(pvm_uint32 chanelNum, pvm_int32 value);

	virtual pvm_bool GetPanning(pvm_uint32 chanelNum, pvm_int32& value);
	virtual pvm_bool GetVolume(pvm_uint32 chanelNum, pvm_int32& value);
	virtual pvm_bool GetLoopCount(pvm_uint32 chanelNum, pvm_int32& value);
	virtual pvm_bool GetLoopInSamples(pvm_uint32 chanelNum, pvm_int64 &loopFrom, pvm_int64 &loopTo);
	virtual pvm_bool GetLoopInMS(pvm_uint32 chanelNum, pvm_int32 &loopFrom, pvm_int32 &loopTo);

	virtual pvm_bool GetPause(pvm_uint32 chanelNum, pvm_bool& value);
	virtual pvm_bool GetRenderSilentVoice(pvm_uint32 chanelNum, pvm_bool& value);
	virtual pvm_bool GetRate(pvm_uint32 chanelNum, pvm_int32& value);

	virtual pvm_bool SetPositionMS(pvm_uint32 chanelNum, pvm_int32 value);
	virtual pvm_bool GetPositionMS(pvm_uint32 chanelNum, pvm_int32& value);

	virtual pvm_bool SetOption(const pvm_char* optionName, void* param, pvm_uint32 paramSize);
	virtual pvm_bool GetOption(const pvm_char* optionName, void* param, pvm_uint32* paramSize);

	virtual pvm_bool SetVoiceOption(pvm_uint32 chanelNum, const pvm_char* optionName, void* param, pvm_uint32 paramSize);
	virtual pvm_bool GetVoiceOption(pvm_uint32 chanelNum, const pvm_char* optionName, void* param, pvm_uint32* paramSize);

	virtual pvm_bool BeginBatchParams();
	virtual void EndBatchParams();

	virtual pvm_bool SetPanningVolumeRateFast(pvm_uint32 chanelNum, pvm_int32 panning, pvm_int32 volume, pvm_int32 rate);

	virtual void OnIdle();
	virtual void SetForceProcessingOnIdle(pvm_bool flag);

	pvm_bool IsFreeSlotsDelayed();
protected:
	PVMVoiceSlot*		voicesSlots;
	pvm_uint32			maxVoices;
	pvm_uint32			voicesActive;
	pvm_bool			mixerInitialized;
	PVMCriticalSection	renderCritical;
	pvm_uint32			globalVolume;

	pvm_uint32	sampleRate;
	pvm_uint32	bitsPerSample;
	pvm_uint32	bytesPerSample;
	pvm_uint32	chanelsNum;
	pvm_bool	unsignedOutput;

	pvm_int8*	renderBuffer;
	pvm_uint32	renderBufferSize;
	pvm_bool	forceProcessOnIdle;
};

pvm_uint32 FillBufferFromVoice(IPVMVoice* voice, void *buffer, pvm_uint32 numSamples, pvm_uint32 bitsPerSample);

#endif
